package com.example.project.bootstrap.extend;




import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.lang.Nullable;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.TransactionSynchronizationManager;

/**
 * @author：balthie@126.com
 * @createtime ： 2022年9月9日 上午10:37:03
 * @description 无资源事务管理器，用于开启空事务（不会真实提交或回滚数据库）
 * @see  org.springframework.batch.support.transaction.ResourcelessTransactionManager
 * @since version 初始于版本 3.1.6
 */
@SuppressWarnings("serial")
public class ResourcelessTransactionManager extends AbstractPlatformTransactionManager {

   @Override
   protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException {
       ((ResourcelessTransaction) transaction).begin();
   }

   @Override
   protected void doCommit(DefaultTransactionStatus status) throws TransactionException {
       if (logger.isDebugEnabled()) {
           logger.debug("Committing resourceless transaction on [" + status.getTransaction() + "]");
       }
   }

   @Override
   protected Object doGetTransaction() throws TransactionException {
       Object transaction = new ResourcelessTransaction();
       List<Object> resources;
       if (!TransactionSynchronizationManager.hasResource(this)) {
           resources = new ArrayList<>();
           TransactionSynchronizationManager.bindResource(this, resources);
       }
       else {
           @SuppressWarnings("unchecked")
           List<Object> stack = (List<Object>) TransactionSynchronizationManager.getResource(this);
           resources = stack;
       }
       resources.add(transaction);
       return transaction;
   }

   @Override
   protected void doRollback(DefaultTransactionStatus status) throws TransactionException {
       if (logger.isDebugEnabled()) {
           logger.debug("Rolling back resourceless transaction on [" + status.getTransaction() + "]");
       }
   }

   @Override
   protected boolean isExistingTransaction(Object transaction) throws TransactionException {
       if (TransactionSynchronizationManager.hasResource(this)) {
           List<?> stack = (List<?>) TransactionSynchronizationManager.getResource(this);
           return stack.size() > 1;
       }
       return ((ResourcelessTransaction) transaction).isActive();
   }

   @Override
   protected void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException {
   }

   @Override
   protected void doCleanupAfterCompletion(Object transaction) {
       List<?> resources = (List<?>) TransactionSynchronizationManager.getResource(this);
       resources.clear();
       TransactionSynchronizationManager.unbindResource(this);
       ((ResourcelessTransaction) transaction).clear();
   }
   
   /**
    * adapt DataSourceTransactionManager
    */
   @Nullable
   private DataSource dataSource;
   
   public void setDataSource(@Nullable DataSource dataSource) {
   }
   
   @Nullable
   public DataSource getDataSource() {
       return this.dataSource;
   }

   private static class ResourcelessTransaction {

       private boolean active = false;

       public boolean isActive() {
           return active;
       }

       public void begin() {
           active = true;
       }

       public void clear() {
           active = false;
       }

   }

}
